package org.jsola.hr.task;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.jsola.hr.common.DateUtils;
import org.jsola.hr.dao.IAttendPunchDailySummaryDAO;
import org.jsola.hr.entity.*;
import org.jsola.hr.query.AttendPunchDeptQuery;
import org.jsola.hr.query.AttendPunchRecordQuery;
import org.jsola.hr.query.AttendPunchStaffQuery;
import org.jsola.hr.query.EmpDepQuery;
import org.jsola.hr.service.*;
import org.jsola.hr.vo.StaffVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 统计打卡人员前一天 上班缺卡、下班缺卡的次数
 *
 * @author WXZ
 */
@Slf4j
@Component
public class MissCardDailyStatTask {

    @Autowired
    private IAttendPunchDailySummaryService attendPunchDailySummaryService;
    @Autowired
    private IAttendPunchDailySummaryDAO attendPunchDailySummaryDAO;
    @Autowired
    private IAttendPunchStaffService attendPunchStaffService;
    @Autowired
    private IAttendPunchDeptService attendPunchDeptService;
    @Autowired
    private IEmpDepService empDepService;
    @Autowired
    private IEmpInfoService empInfoService;
    @Autowired
    private IAttendPunchRecordService attendPunchRecordService;
    @Autowired
    private IAttendPeopleMonthlyStatService attendPeopleMonthlyStatService;

    /**
     *
     */
    @Scheduled(cron = "30 10 4 * * ?") // 每天4点10分30秒触发
    public void missCardDailyStat() {

        log.info("统计打卡人员前一天 上班缺卡、下班缺卡的次数");

        // 昨日
        String dateStr = DateFormatUtils.format(new Date(), "yyyy-MM-dd");
        dateStr = DateUtils.getPreDateByDate(dateStr);

        // 查询考勤打卡日汇总
        Example example = new Example(AttendPunchDailySummaryDO.class);
        example.and().andEqualTo("valid", true);
        example.and().andEqualTo("yearly", dateStr.split("-")[0]);
        example.and().andEqualTo("monthly", dateStr.split("-")[1]);
        example.and().andEqualTo("daily", dateStr.split("-")[2]);
        List<AttendPunchDailySummaryDO> summaryList = attendPunchDailySummaryDAO.selectByExample(example);
        if (summaryList == null || summaryList.size() <= 0) {
            return;
        }

        for (AttendPunchDailySummaryDO summary : summaryList) {

            // 查询考勤规则下的所有考勤人员
            Set<StaffVO> staffIds = new HashSet<StaffVO>();

            // 查询考勤打卡参与人员
            Set<StaffVO> set1 = this.getStaffSetForPunchStaff(summary.getAttendPlanId(), summary.getSiteId());
            if (set1.size() > 0) {
                for (StaffVO staffVO : set1) {
                    staffIds.add(staffVO);
                }
            }

            // 查询考勤打卡参与部门
            Set<StaffVO> set2 = this.getStaffSetForPunchDep(summary.getAttendPlanId(), summary.getSiteId());
            if (set2.size() > 0) {
                for (StaffVO staffVO : set2) {
                    staffIds.add(staffVO);
                }
            }

            // 遍历每个打卡人员
            if (staffIds.size() <= 0) {
                continue;
            }

            for (StaffVO staff : staffIds) {

                boolean onWorkMissFlag = true;
                boolean offWorkMissFlag = true;

                // 查询每个打卡人员每天是否有上班或者下班的打卡记录
                AttendPunchRecordQuery attendPunchRecordQuery = new AttendPunchRecordQuery();
                attendPunchRecordQuery.setYear(summary.getYearly());
                attendPunchRecordQuery.setMonth(summary.getMonthly());
                attendPunchRecordQuery.setDay(summary.getDaily());
                attendPunchRecordQuery.setEmpInfoId(staff.getEmpInfoId());
                List<AttendPunchRecordDO> punchRecordList = attendPunchRecordService.selectDO(attendPunchRecordQuery, summary.getSiteId());
                if (punchRecordList.size() <= 0) {
                    // 更新 - 上班也缺卡下班也缺卡
                    AttendPunchDailySummaryDO dailySummaryDO = new AttendPunchDailySummaryDO();
                    dailySummaryDO.setId(summary.getId());
                    dailySummaryDO.setOnWorkMissPeoples(summary.getOnWorkMissPeoples() + 1);
                    dailySummaryDO.setOffWorkMissPeoples(summary.getOffWorkMissPeoples() + 1);
                    dailySummaryDO.setGmtModified(new Date());
                    attendPunchDailySummaryDAO.updateByPrimaryKeySelective(dailySummaryDO);
                }
                else {

                    for (AttendPunchRecordDO record : punchRecordList) {

                        if (record.getPunchType() == 1) {
                            onWorkMissFlag = false;
                            break;
                        }

                        if (record.getPunchType() == 2) {
                            offWorkMissFlag = false;
                            break;
                        }
                    }

                    // 如果缺了上班的卡
                    if (onWorkMissFlag) {
                        AttendPunchDailySummaryDO dailySummaryDO = new AttendPunchDailySummaryDO();
                        dailySummaryDO.setId(summary.getId());
                        dailySummaryDO.setOnWorkMissPeoples(summary.getOnWorkMissPeoples() + 1);
                        dailySummaryDO.setGmtModified(new Date());
                        attendPunchDailySummaryDAO.updateByPrimaryKeySelective(dailySummaryDO);
                    }

                    // 如果缺了下班的卡
                    if (offWorkMissFlag) {
                        AttendPunchDailySummaryDO dailySummaryDO = new AttendPunchDailySummaryDO();
                        dailySummaryDO.setId(summary.getId());
                        dailySummaryDO.setOffWorkMissPeoples(summary.getOffWorkMissPeoples() + 1);
                        dailySummaryDO.setGmtModified(new Date());
                        attendPunchDailySummaryDAO.updateByPrimaryKeySelective(dailySummaryDO);

                        // 更新月统计
                    }

                }
            }
        }

    }

    /**
     * 从打卡人员当中获取打卡人员
     *
     * @param attendPlanId
     * @param siteId
     */
    private Set<StaffVO> getStaffSetForPunchStaff(String attendPlanId, String siteId) {

        Set<StaffVO> staffIds = new HashSet<StaffVO>();

        // 查询考勤打卡参与人员
        AttendPunchStaffQuery attendPunchStaffQuery = new AttendPunchStaffQuery();
        attendPunchStaffQuery.setAttendPlanId(attendPlanId);
        List<AttendPunchStaffDO> staffList = attendPunchStaffService.selectDO(attendPunchStaffQuery, siteId);
        if (staffList != null && staffList.size() > 0) {
            for (AttendPunchStaffDO attendPunchStaff : staffList) {

                StaffVO staffVO = new StaffVO();
                staffVO.setEmpInfoId(attendPunchStaff.getEmpInfoId());
                staffVO.setEmpInfoName(attendPunchStaff.getEmpInfoName());
                staffIds.add(staffVO);
            }
        }

        return staffIds;
    }

    /**
     * 从考勤部门当中获取打卡人员
     *
     * @param attendPlanId
     * @param siteId
     * @return
     */
    private Set<StaffVO> getStaffSetForPunchDep(String attendPlanId, String siteId) {

        Set<StaffVO> staffIds = new HashSet<StaffVO>();

        // 查询考勤打卡参与部门
        AttendPunchDeptQuery attendPunchDeptQuery = new AttendPunchDeptQuery();
        attendPunchDeptQuery.setAttendPlanId(attendPlanId);
        List<AttendPunchDeptDO> deptList = attendPunchDeptService.selectDO(attendPunchDeptQuery, siteId);
        if (deptList != null && deptList.size() > 0) {
            for (AttendPunchDeptDO dept : deptList) {

                // 查询部门下的人员
                EmpDepQuery empDepQuery = new EmpDepQuery();
                empDepQuery.setDepId(dept.getDeptId());
                List<EmpDepDO> empDepList = empDepService.selectDO(empDepQuery, dept.getSiteId());
                if (empDepList.size() > 0) {
                    for (EmpDepDO empDep : empDepList) {

                        // 查询人员信息
                        EmpInfoDO empInfoDO = empInfoService.selectDOById(empDep.getEmpId(), empDep.getSiteId());
                        if (empInfoDO != null) {
                            StaffVO staffVO = new StaffVO();
                            staffVO.setEmpInfoId(empInfoDO.getId());
                            staffVO.setEmpInfoName(empInfoDO.getName());
                            staffIds.add(staffVO);
                        }
                    }
                }
            }
        }

        return staffIds;
    }


}
